package dmt16.TelemetrySuit.UI.PlotTools
{
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	
	public class Graph extends Sprite
	{
		public function Graph()
		{
			_axes.cacheAsBitmap=true;
			_lines=new Vector.<GraphLine>();
			addChild(_axes);
			_axes.mask=_mask;
			_axes.addChild(_mask);
			showNavigator=true;
		}
		
		private var _axes:Sprite=new Sprite();
		
		private var _lines:Vector.<GraphLine>;
		
		private var _mask:Shape=new Shape();
		
		public function addLine(line:GraphLine):void{
			_lines.push(line);
			_axes.addChild(line);
		}
		
		private var _width:Number=200;
		public override function get width():Number{
			return _width;
		}
		public override function set width(value:Number):void{
			_width=value;
		}
		
		private var _height:Number=100;
		public override function get height():Number{
			return _height;
		}
		public override function set height(value:Number):void{
			_height=value;
		}
		
		public function setSize(width:Number,height:Number):void{
			_width=width;
			_height=height;
			redraw();
		}
		
		private var _yLimMin:Number=0;
		private var _yLimMax:Number=1;
		
		public function yLim(min:Number,max:Number):void{
			_yLimManual=true;
			_yLimMin=min;
			_yLimMax=max;
		}
		
		private var _yLimManual:Boolean=false;
		public function get yLimAuto():Boolean{
			return _yLimManual;	
		}
		public function set yLimAuto(mode:Boolean):void{
			_yLimManual=mode;
			redraw();
		}
		
		private var _xLimMin:Number=0;
		private var _xLimMax:Number=1;
		
		public function xLim(min:Number,max:Number):void{
			_xLimManual=false;
			_xLimMin=min;
			_xLimMax=max;
		}
		
		private var _xLimManual:Boolean=false;
		public function get xLimManual():Boolean{
			return _xLimManual;	
		}
		public function set xLimManual(mode:Boolean):void{
			_xLimManual=mode;
			redraw();
		}
		
		public function fullRedraw():void{
			_xLimManual=false;
			if(_showNavigator){
				_navigator.y=_height-_navigator.height;
				_navigator.width=_width;
				_navigator.height=80;
				
				_navigator.startPosition=0;
				_navigator.endPosition=1;
			}
			redraw();
		}
		
		private var M:Matrix=new Matrix;
		
		private var _navigator:GraphNavigator=null;
		private var _showNavigator:Boolean=false;
		public function set showNavigator(visible:Boolean):void{
			if(visible&&!_showNavigator){
				_navigator=new GraphNavigator();
				_navigator.width=_width;
				_navigator.height=80;
				addChild(_navigator);
				_showNavigator=true;
				_navigator.addEventListener(GraphNavigator.LIMITS_CHANGED,_onLimitsChanged);
			}
			else if(!visible&&_showNavigator){
				removeChild(_navigator);
				_showNavigator=false;
				_navigator=null;
			}
			
		}
		
		private function _onLimitsChanged(event:Event):void{
			_xLimManual=true;
			var xmin:Number=0;
			var xmax:Number=0;
			for each(var l:GraphLine in _lines){
				xmin=Math.min(xmin,l.minX);
				xmax=Math.max(xmax,l.maxX);
			}
			
			_xLimMin=xmin+(xmax-xmin)*_navigator.startPosition;
			_xLimMax=xmin+(xmax-xmin)*_navigator.endPosition;
			
			if(_navigator.startPosition==0&&_navigator.endPosition==1)
				_xLimManual=false;
			redraw();
		}
		
		public function redraw():void{
			_mask.graphics.clear();
			_mask.graphics.beginFill(0);
			_mask.graphics.drawRect(-1,-1,_width+2,(_showNavigator?_height-120:_height)+2);
			
			var xmin:Number=0;
			var xmax:Number=0;
			var ymin:Number=0;
			var ymax:Number=0;
			
			if(_yLimManual){
				ymin=_yLimMin;
				ymax=_yLimMax;
			}
			
			if(_xLimManual){
				xmin=_xLimMin;
				xmax=_xLimMax;
			}
			
			for each(var l:GraphLine in _lines){
				if(l.visible){
					if(!_xLimManual){
						xmin=Math.min(xmin,l.minX);
						xmax=Math.max(xmax,l.maxX);
					}
					if(!_yLimManual){
						ymin=Math.min(ymin,l.minY);
						ymax=Math.max(ymax,l.maxY);
					}
				}
			}
			
			var scaleX:Number=_width/(xmax-xmin);
			var scaleY:Number=(_showNavigator?_height-120:_height)/(ymax-ymin);
			if((ymax-ymin)==0)
				scaleY=0;
			_axes.graphics.clear();
			_axes.graphics.lineStyle(1.5,0xFFCCCCCC);
			_axes.graphics.moveTo(-xmin*scaleX,0);
			_axes.graphics.lineTo(-xmin*scaleX,(_showNavigator?_height-120:_height));
			_axes.graphics.moveTo(0,ymax*scaleY);
			_axes.graphics.lineTo(_width,ymax*scaleY);
						
			for each(l in _lines){
				if(l.visible){
					l.draw(scaleX,scaleY);
					l.x=-xmin*scaleX;
					l.y=ymax*scaleY;
				}
			}
			
			if(!xLimManual){		
				M.setTo(1,0,0,_navigator.height/(_height-(_navigator.height+40)),0,0);
				
				var bmpData:BitmapData=new BitmapData(_width,80,true,0);
				bmpData.draw(_axes,M,null,null,null,true);
				
				_navigator.bmp.bitmapData=bmpData;
			}
		}
	}
}